package com.mljr.example.http;


import com.ctakit.sdk.app.HttpUtils;
import com.ctakit.sdk.exception.BusinessException;
import com.ctakit.sdk.util.JsonUtils;
import com.mljr.example.BuildConfig;
import com.mljr.example.bean.Result;
import com.mljr.example.util.AppUtils;
import com.orhanobut.logger.Logger;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public abstract class BaseHttpServices {

	/** 请求方式 **/

	private enum HttpMethod {
		PUT,UPLOAD_PUT,GET, POST, MULTIPART,POST_BODY;
	}


	/**
	 * http 请求
	 * 
	 * @param url
	 * @param httpMethod
	 * @param params
	 * @param checkToken
	 * @return
	 */
	private static <T> Result getResultByHttp(String url, HttpMethod httpMethod, Map<String, String> params, boolean checkToken) throws BusinessException {
		Result result = getDataByHttp( url, httpMethod, params, Result.class, checkToken);
		
		if (result.getErrcode() != 0) {// 操作出错
			if (result.getErrcode() == 500) {
				throw new BusinessException("服务器开小差了，请稍后重试", 500);
			} else {
				throw new BusinessException(result.getErrmsg(), result.getErrcode());
			}

		} else {// 操作成功
			return result;
		}

	}
	
	public static <T> T uploadDataByPut(String url, Map<String, String> params, Class<T> clazz , boolean checkToken) throws BusinessException {
		// TODO Auto-generated method stub
		return getResultDataByPut(url, params,clazz,true, checkToken);
	}


	private static <T> T getDataByHttp(String url, HttpMethod httpMethod, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		T result = null;
		String json = null;
		url = AppUtils.getSystemInfoUrl(url);
        if(params==null){
            params = new TreeMap<>();
        }

		if(BuildConfig.DEBUG) {
			Logger.t("http").d("url:" + url + "");

			if (params != null && params.size() > 0) {
				for (Map.Entry<String, String> map : params.entrySet()) {
					Logger.t("http").d("参数-" + map.getKey() + ":" + map.getValue());
				}
			}
		}
		switch (httpMethod) {
		case GET:
			json = HttpUtils.get(url, params);
			break;
		case POST:
			json = HttpUtils.post( url, params);
			break;
		case PUT:
			json = HttpUtils.post( url, params);
			break;
		case UPLOAD_PUT:
			json = HttpUtils.post( url, params,true);
			break;

		case MULTIPART:
			json = HttpUtils.multipartPost(url, params);
			break;
		case POST_BODY:
			if(params!=null&&params.get(RequestData.JsonBodyData)!=null){
				json = HttpUtils.postBody( url, params.get(RequestData.JsonBodyData));
			}else{
				json = HttpUtils.postBody( url, JsonUtils.toJson(params));
			}

			break;

		default:
			json = HttpUtils.post(url, params);
			break;
		}
		try{
			result = JsonUtils.fromJson(json, clazz);

            Logger.t("http").json(json);

		}catch(Exception e){
			throw new BusinessException(HttpUtils.errorMsg, 500);
		}

		if(result==null){
			throw new BusinessException(HttpUtils.errorMsg, 500);
		}
		return result;

	}

	private static <T> List<T> getListDataByHttp( String url, HttpMethod httpMethod, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		List<T> result = null;
		String json = null;

		url = AppUtils.getSystemInfoUrl(url);
        if(params==null){
            params = new TreeMap<>();
        }
        //params.put("di", DeviceUtil.getDeviceID());
        //params.put("ui",Global.getUserId()+"");
        //params.put("token", Global.getToken());
		if(BuildConfig.DEBUG) {
			Logger.t("http").d("url:" + url + "");

			if (params != null && params.size() > 0) {
				for (Map.Entry<String, String> map : params.entrySet()) {
					Logger.t("http").d("参数-" + map.getKey() + ":" + map.getValue());
				}
			}
		}
		switch (httpMethod) {
			case GET:
				json = HttpUtils.get(url, params);
				break;
			case POST:
				json = HttpUtils.post(url, params);
				break;
			case PUT:
				json = HttpUtils.post(url, params);
				break;
			case UPLOAD_PUT:
				json = HttpUtils.post(url, params,true);
				break;

			case MULTIPART:
				json = HttpUtils.multipartPost(url, params);
				break;
			case POST_BODY:
				json = HttpUtils.postBody(url, JsonUtils.toJson(params));
				break;

			default:
				json = HttpUtils.post(url, params);
				break;
		}
		try{
			result = JsonUtils.fromJsonToList(json, clazz);

			return result;

		}catch(Exception e){
			throw new BusinessException(HttpUtils.errorMsg, 500);
		}


	}

	public static <T> T getDataByGet(String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		return getDataByHttp(url, HttpMethod.GET, params, clazz, checkToken);
	}

	public static <T> T getDataByPost( String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		return getDataByHttp(url, HttpMethod.POST, params, clazz, checkToken);
	}

	public static <T> T getDataByPut(String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		return getDataByHttp(url, HttpMethod.PUT, params, clazz, checkToken);
	}

	public static boolean isString(Class<?> clazz) {
		return (clazz != null) && ((String.class.isAssignableFrom(clazz)) || (Character.TYPE.isAssignableFrom(clazz)) || (Character.class.isAssignableFrom(clazz)));
	}

	/** 是否布尔值 **/
	public static boolean isBoolean(Class<?> clazz) {
		return (clazz != null) && ((Boolean.TYPE.isAssignableFrom(clazz)) || (Boolean.class.isAssignableFrom(clazz)));
	}

	@SuppressWarnings("unchecked")
	protected static <T> T getResultDataByGet(String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		Result result = getResultByHttp(url, HttpMethod.GET, params, checkToken);
		if (clazz == null) {
			return (T) Boolean.TRUE;
		} else {
			if (isString(clazz)) {
				return (T) result.getData();
			} else if (isBoolean(clazz)) {
				return (T) Boolean.TRUE;
			} else {
				return JsonUtils.fromJson(result.getData(), clazz);
			}

		}

	}
	
	protected static <T> T getResultDataByPut(String url, Map<String, String> params, Class<T> clazz, boolean upload,boolean checkToken) throws BusinessException {
		Result result = null;
		if(upload){
			 result = getResultByHttp(url, HttpMethod.UPLOAD_PUT, params, checkToken);
		}else{
			result = getResultByHttp(url, HttpMethod.PUT, params, checkToken);
		}
		
		if (clazz == null) {
			return (T) Boolean.TRUE;
		} else {
			if (isString(clazz)) {
				return (T) result.getData();
			} else if (isBoolean(clazz)) {
				return (T) Boolean.TRUE;
			} else {
				return JsonUtils.fromJson(result.getData(), clazz);
			}

		}

	}

	protected static <T> T getResultDataByPut(String url, Class<T> clazz,boolean upload, boolean checkToken) throws BusinessException {
		return getResultDataByPut(url, null, clazz, upload, checkToken);
	}

	protected static <T> T getResultDataByGet(String url, Class<T> clazz, boolean checkToken) throws BusinessException {
		return getResultDataByGet(url, null, clazz, checkToken);
	}

	protected static <T> List<T> getResultListDataByGet( String url, Class<T> clazz, boolean checkToken) throws BusinessException {
		return getResultListDataByGet(url, null, clazz, checkToken);
	}

	protected static <T> List<T> getResultListDataByGet(String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		Result result = getResultByHttp(url, HttpMethod.GET, params, checkToken);
		return JsonUtils.fromJsonToList(result.getData(), clazz);
	}

	@SuppressWarnings("unchecked")
	protected static <T> T getMultipartResultDataByPost(String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		Result result = getResultByHttp( url, HttpMethod.MULTIPART, params, checkToken);
		if (clazz == null) {
			return (T) Boolean.TRUE;
		} else {
			if (isString(clazz)) {
				return (T) result.getData();
			} else if (isBoolean(clazz)) {
				return (T) Boolean.TRUE;
			} else {
				return JsonUtils.fromJson(result.getData(), clazz);
			}

		}
	}

	@SuppressWarnings("unchecked")
	protected static <T> T getResultDataByPost(String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		Result result = getResultByHttp(url, HttpMethod.POST, params, checkToken);
		if (clazz == null) {
			return (T) Boolean.TRUE;
		} else {
			if (isString(clazz)) {
				return (T) result.getData();
			} else if (isBoolean(clazz)) {
				if("false".equalsIgnoreCase(result.getData())){
					return (T) Boolean.FALSE;
				}else{
					return (T) Boolean.TRUE;
				}

			} else {
				return JsonUtils.fromJson(result.getData(), clazz);
			}

		}
	}
	protected static <T> T getResultDataByPost(String url, Map<String, String> params, Type type, boolean checkToken) throws BusinessException {
		Result result = getResultByHttp(url, HttpMethod.POST, params, checkToken);
		if (type == null) {
			return (T) Boolean.TRUE;
		} else {
			return JsonUtils.fromJson(result.getData(), type);
			
		}
	}
	@SuppressWarnings("unchecked")
	protected static <T> T getResultDataByPostBody(String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		Result result = getResultByHttp(url, HttpMethod.POST_BODY, params, checkToken);
		if (clazz == null) {
			return (T) Boolean.TRUE;
		} else {
			if (isString(clazz)) {
				return (T) result.getData();
			} else if (isBoolean(clazz)) {
				return (T) Boolean.TRUE;
			} else {
				return JsonUtils.fromJson(result.getData(), clazz);
			}
			
		}
	}

	protected static <T> List<T> getResultListDataByPost( String url, Map<String, String> params, Class<T> clazz, boolean checkToken) throws BusinessException {
		Result result = getResultByHttp(url, HttpMethod.POST, params, checkToken);
		return JsonUtils.fromJsonToList(result.getData(), clazz);
	}



}
